#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

// token types
enum{
  // operators:
  T_EOF, 
  T_PLUS, T_MINUS, 
  T_STAR, T_SLASH,
  T_EQ, T_NE,
  T_LT, T_GT, T_LE, T_GE,
  // type keywords:
  T_VOID, T_CHAR, T_INT, T_LONG,
  // structural tokens:
  T_INTLIT, T_SEMI, T_ASSIGN, T_IDENT,
  T_LBRACE, T_RBRACE, T_LPAREN, T_RPAREN, // brace and paren 
  // other keywords:
  T_PRINT, T_IF, T_ELSE, T_WHILE, T_FOR, T_RETURN
};

struct token
{
  int token;
  int intvalue;
};

// AST node types.
enum{
  A_ADD = 1, A_SUBTRACT, A_MULTIPLY, A_DIVIDE, 
  A_EQ, A_NE, A_LT, A_GT, A_LE, A_GE, 
  A_INTLIT,
  A_IDENT, A_LVIDENT, A_ASSIGN, A_PRINT, A_GLUE, 
  A_IF, A_WHILE, A_FUNCTION, A_WIDEN, A_RETURN,
  A_FUNCCALL
};

// primitive types.
enum{
  P_NONE, P_VOID, P_CHAR, P_INT, P_LONG
};


// abstract syntax tree structure
struct ASTnode{
  int op;
  int type;
  struct ASTnode* left;
  struct ASTnode* mid;
  struct ASTnode* right;
  union{
    int intvalue;
    int id; // for A_IDENT, the symbol slot number
  }v;
};


// structural types.
enum{
  S_VARIABLE, S_FUNCTION
};

// symbol table
struct symtable{
  int type;        // primitive type for the symbol.
  int stype;       // structural type for the symbol.
  int endlabel;    // for S_FUNCTIONs, the end label.
  char* name;
};




